package com.ruoyi.web.controller.employ;

import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.excel.annotation.ExcelProperty;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.ExcelUtil1;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.domain.WorkEmployTitle;
import com.ruoyi.system.domain.vo.WorkEmployExcportDTO;
import com.ruoyi.system.domain.vo.WorkEmployPositionDTO;
import com.ruoyi.system.domain.vo.WorkEmployPositionFutureDTO;
import com.ruoyi.system.domain.vo.WorkEmployPositionNextDTO;
import com.ruoyi.system.domain.vo.WorkEmployTitleDTO;
import com.ruoyi.system.service.IWorkEmployTitleService;

/**
 * 招聘信息Controller
 * 
 * @author ruoyi
 * @date 2024-08-14
 */
@RestController
@RequestMapping("/system/title")
public class WorkEmployTitleController extends BaseController
{
    @Autowired
    private IWorkEmployTitleService workEmployTitleService;

    /**
     * 查询招聘信息列表
     */
    @GetMapping("/list")
    public TableDataInfo list(WorkEmployTitle workEmployTitle)
    {
        List<WorkEmployTitle> list = workEmployTitleService.selectWorkEmployTitleList(workEmployTitle);
        return getDataTable(list);
    }

    /**
     * 导出招聘信息列表
     * @throws Exception 
     */
    @Log(title = "招聘信息", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, WorkEmployTitle workEmployTitle) throws Exception
    {
    	WorkEmployExcportDTO workEmployExcportDTO = workEmployTitleService.selectWorkEmployTitleListExport(workEmployTitle);
        //String s = JSON.toJSONString(list);

        String year = workEmployTitle.getYear();
        String lable1 = year+"年计划招聘";
        String lable2 = (Integer.parseInt(year)+1)+"年计划招聘";
        String lable3 = (Integer.parseInt(year)+2)+"至"+(Integer.parseInt(year)+4)+"年计划招聘";
        
      //  List<WorkEmployTitleDTO> list1= JSON.parseArray(s, WorkEmployTitleDTO.class);
        // 替换注解中的属性值为
        HashMap<String, String> replaceMap = new HashMap<>();
        replaceMap.put("2024年计划招聘", lable1);
        replaceMap.put("2025年计划招聘", lable2);
        replaceMap.put("2026至2029年计划招聘", lable3);

     	
        /*
         * 这里简单的说明一下：
         *      attrName: 对应的是 @ExcelProperty 中的 value 属性
         *      attrTypeEnum: 对应的是 @ExcelProperty 中的 value 属性 的类型
         */
        AnnotationUtils.changeAnnotationValueToDealProcess(
        		WorkEmployTitleDTO.class, ExcelProperty.class, "value", AnnotationUtils.AttrTypeEnum.STRING_ARR, replaceMap, new AnnotationUtils.DealProcess() {
                    @Override
                    public void deal() {
                        
                     	try {
                            List<WorkEmployTitleDTO> excelEntities = new ArrayList<>();
                            byte[] dataByte =  ExcelUtil1.exportWorkBookData("c:/temp/11s.xlsx",workEmployExcportDTO.getDataNames(), workEmployExcportDTO.getDatas(),workEmployExcportDTO.getModules());
                        	
                            FileInputStream inputStream = null;
                    		OutputStream outputStream = null;
                            // 让浏览器用utf8来解析返回的数据
                			response.setHeader("Content-type", "text/html;charset=UTF-8");
                			// servlet用UTF-8转码，而不是用默认的ISO8859
                			response.setCharacterEncoding("UTF-8");
                			response.setContentType("application/force-download");
                			response.setHeader("Content-Disposition",
                					"attachment;filename=" + URLEncoder.encode("导入模板", "utf-8"));
                			outputStream = response.getOutputStream();
                			outputStream.write(dataByte);
                			outputStream.flush();
                			outputStream.close();
                			}catch(Exception ex) {
                				
                			}
                    }
                }
        );
     
       // ExcelUtil<WorkEmployTitle> util = new ExcelUtil<WorkEmployTitle>(WorkEmployTitle.class);
        //util.exportExcel(response, list, "招聘信息数据");
    }

    /**
     * 获取招聘信息详细信息
     */
    @GetMapping(value = "/{employId}")
    public AjaxResult getInfo(@PathVariable("employId") Integer employId)
    {
        return success(workEmployTitleService.selectWorkEmployTitleByEmployId(employId));
    }

    /**
     * 新增招聘信息
     */
    @Log(title = "招聘信息", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody WorkEmployTitle workEmployTitle)
    {
        return success(workEmployTitleService.insertWorkEmployTitle(workEmployTitle));
    }

    /**
     * 修改招聘信息
     */
    @Log(title = "招聘信息", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody WorkEmployTitle workEmployTitle)
    {
        return toAjax(workEmployTitleService.updateWorkEmployTitle(workEmployTitle));
    }

    /**
     * 删除招聘信息
     */
    @Log(title = "招聘信息", businessType = BusinessType.DELETE)
	@DeleteMapping("/{employIds}")
    public AjaxResult remove(@PathVariable Integer[] employIds)
    {
        return toAjax(workEmployTitleService.deleteWorkEmployTitleByEmployIds(employIds));
    }

    @PostMapping("/importTemplate")
    public void importTemplate(HttpServletResponse response)
    {
    	
    	WorkEmployTitle workEmployTitle = new WorkEmployTitle();
    	workEmployTitle.setEmployId(24);
    	workEmployTitle.setYear(String.valueOf(getCurrentYear()));
    	WorkEmployExcportDTO workEmployExcportDTO = workEmployTitleService.selectWorkEmployTitleListExport(workEmployTitle);
        //String s = JSON.toJSONString(list);

        String year = workEmployTitle.getYear();
        String lable1 = year+"年计划招聘";
        String lable2 = (Integer.parseInt(year)+1)+"年计划招聘";
        String lable3 = (Integer.parseInt(year)+2)+"至"+(Integer.parseInt(year)+4)+"年计划招聘";
        
      //  List<WorkEmployTitleDTO> list1= JSON.parseArray(s, WorkEmployTitleDTO.class);
        // 替换注解中的属性值为
        HashMap<String, String> replaceMap = new HashMap<>();
        replaceMap.put("2024年计划招聘", lable1);
        replaceMap.put("2025年计划招聘", lable2);
        replaceMap.put("2026至2029年计划招聘", lable3);

     	
        /*
         * 这里简单的说明一下：
         *      attrName: 对应的是 @ExcelProperty 中的 value 属性
         *      attrTypeEnum: 对应的是 @ExcelProperty 中的 value 属性 的类型
         */
        AnnotationUtils.changeAnnotationValueToDealProcess(
        		WorkEmployTitleDTO.class, ExcelProperty.class, "value", AnnotationUtils.AttrTypeEnum.STRING_ARR, replaceMap, new AnnotationUtils.DealProcess() {
                    @Override
                    public void deal() {
                        
                     	try {
                            List<WorkEmployTitleDTO> excelEntities = new ArrayList<>();
                            byte[] dataByte =  ExcelUtil1.exportWorkBookData("c:/temp/11s.xlsx",workEmployExcportDTO.getDataNames(), workEmployExcportDTO.getDatas(),workEmployExcportDTO.getModules());
                        	
                            FileInputStream inputStream = null;
                    		OutputStream outputStream = null;
                            // 让浏览器用utf8来解析返回的数据
                			response.setHeader("Content-type", "text/html;charset=UTF-8");
                			// servlet用UTF-8转码，而不是用默认的ISO8859
                			response.setCharacterEncoding("UTF-8");
                			response.setContentType("application/force-download");
                			response.setHeader("Content-Disposition",
                					"attachment;filename=" + URLEncoder.encode("导入模板", "utf-8"));
                			outputStream = response.getOutputStream();
                			outputStream.write(dataByte);
                			outputStream.flush();
                			outputStream.close();
                			}catch(Exception ex) {
                				
                			}
                    }
                }
        );
    }
	private int getCurrentYear() {
		Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        return year;
	}
    @PostMapping("/importData")
    public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception
    {
 
        InputStream inputStream = file.getInputStream();// 读取input流
        byte[] b = ExcelUtil1.inputStreamToByteArray(inputStream);
        List userList= ExcelUtil1.getWorkBookData(b, WorkEmployTitleDTO.class,0);
        List userList1= ExcelUtil1.getWorkBookData(b, WorkEmployPositionDTO.class,1);
        List userList2= ExcelUtil1.getWorkBookData(b, WorkEmployPositionNextDTO.class,2);
        List userList3= ExcelUtil1.getWorkBookData(b, WorkEmployPositionFutureDTO.class,3);
        System.out.println(userList1);
        workEmployTitleService.importWorkEmployTitle(userList,userList1,userList2,userList3);
        return success("导入成功！");
    }

    
}

/**
 * 注解工具类
 */
class AnnotationUtils {

    /**
     * 变更注解的属性值再处理业务，处理完业务之后恢复类的属性
     *
     * @param clazz     注解所在的实体类
     * @param tClass    注解类
     * @param attrName 要修改的注解属性名
     * @param attrTypeEnum 要修改的注解属性的类型
     * @param valueMap  要设置的属性值
     */
    public static <A extends Annotation> void changeAnnotationValueToDealProcess(
            Class<?> clazz,
            Class<A> tClass,
            String attrName,
            AttrTypeEnum attrTypeEnum,
            Map<String, String> valueMap,
            DealProcess dealProcess) {
        try {

            Map<String, Object> fieldAnnotationValueMap = new HashMap<>();

            Field[] fields = clazz.getDeclaredFields();
            for (Field field : fields) {
                A annotation = field.getAnnotation(tClass);
                if (annotation == null) continue;
                Object value = setAnnotationValue(annotation, attrName, attrTypeEnum, valueMap);
                String fieldName = field.getName();
                fieldAnnotationValueMap.put(fieldName, value);
            }

            // 处理业务逻辑
            dealProcess.deal();

            // 恢复
            for (Field field : fields) {
                A annotation = field.getAnnotation(tClass);
                String fieldName = field.getName();
                if (annotation == null) continue;
                Object value = fieldAnnotationValueMap.get(fieldName);

                InvocationHandler handler = Proxy.getInvocationHandler(annotation);
                Field memberValuesField = handler.getClass().getDeclaredField("memberValues");
                memberValuesField.setAccessible(true);
                @SuppressWarnings("all")
                Map<String, Object> memberValues = (Map) memberValuesField.get(handler);
                memberValues.put(attrName, value);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 设置注解中的字段值
     *
     * @param annotation 要修改的注解实例
     * @param attrName  要修改的注解属性名
     * @param attrTypeEnum 要修改的注解属性的类型
     * @param valueMap   替换属性集的map
     */
    @SuppressWarnings("all")
    private static Object setAnnotationValue(Annotation annotation, String attrName,
                                             AttrTypeEnum attrTypeEnum, Map<String, String> valueMap) throws NoSuchFieldException, IllegalAccessException {
        InvocationHandler handler = Proxy.getInvocationHandler(annotation);
        Field field = handler.getClass().getDeclaredField("memberValues");
        field.setAccessible(true);
        Map memberValues = (Map) field.get(handler);
        Object value = memberValues.get(attrName);
        switch (attrTypeEnum) {
            case STRING: {
                String oldValue = (String) value;
                String newValue = valueMap.get(oldValue);
                if (newValue!=null && !newValue.equals("")) {
                    memberValues.put(attrName, newValue);
                }
            }
            break;
            case STRING_ARR: {
                String[] oldValue = (String[]) value;
                String[] newValue = new String[oldValue.length];
                for (int i = 0; i < oldValue.length; i++) {
                    String replace = valueMap.get(oldValue[i]);
                    newValue[i] = replace != null ? replace : oldValue[i];
                }
                memberValues.put(attrName, newValue);
            }
            break;
        }
        return value;
    }

    public enum AttrTypeEnum {
        STRING,
        STRING_ARR
    }

    public interface DealProcess {

        void deal() throws Exception;

    }

}

